// 创建ws
class webSocket {
  ws = null; // ws 对象
  receiver = null; // 接受函数
  msglist = []; // 及时数组
  cachelist = new Map(); // 缓存数组
  static instance = null
  url = '';
  constructor(option) {
    this.url =
      option.url ||
      'ws://47.242.25.96:10000/websocket/quote?_=1607675853653&_s=d1e829d321b235cbc31a0539cd5a986d'
    this.createWs()
  }

  // 获取实例 // 单列模式
  static getInstance(option = { url: '' }) {
    if (!webSocket.instance) {
      webSocket.instance = new webSocket(option)
    }
    return webSocket.instance
  }

  // 创建ws
  createWs() {
    if ('WebSocket' in window) {
      this.ws = new WebSocket(this.url)
      this.ws.onclose = this.close.bind(this)
      this.heartBeat()
    } else {
      alert('Not support websocket')
    }
  }

  // 心跳机制
  heartBeat() {
    this.heartBeatTimer = setInterval(() => {
      if (this.ws.readyState !== 1) return
      this.setMsg({
        name: 'ping',
        sub: 'ping'
      })
    }, 5000)
  }

  // 遍历发送信息
  forEachSendMsg() {
    for (let i = 0; i < this.msglist.length; i++) {
      const msg = this.msglist[i]
      this.ws.send(msg)
    }
    this.msglist = []
  }

  // 设置请求参数
  setMsg(msg) {
    // msg 为数组形式
    if (msg instanceof Array) {
      if (!msg.length) return
      msg.forEach((item, i) => {
        const name = item.name.trim()
        delete item.name
        this.msglist.push(JSON.stringify(item))
        this.cachelist.set(name, JSON.stringify(item))
      })
    } else {
      const name = msg.name.trim()
      delete msg.name
      this.msglist.push(JSON.stringify(msg))
      this.cachelist.set(name, JSON.stringify(msg))
    }

    if (this.ws.readyState === 1) {
      this.forEachSendMsg()
    }
  }

  // 开始接受信息  receiver 回调函数
  start(receiver) {
    this.receiver = receiver
    if (this.ws.readyState === 0) {
      this.ws.onopen = () => {
        this.forEachSendMsg()
        this.ws.onmessage = this.receiver
      }
    } else {
      this.forEachSendMsg()
      this.ws.onmessage = this.receiver
    }
  }

  // 设置请求暂停参数
  pause(msg) {
    if (msg instanceof Array) {
      if (!msg.length) return
      msg.forEach((item, i) => {
        const name = item.name.trim()
        delete item.name
        this.ws.send(JSON.stringify(item))
        this.cachelist.delete(name)
      })
    } else if (msg instanceof Object) {
      const name = msg.name.trim()
      delete msg.name
      this.ws.send(JSON.stringify(msg))
      this.cachelist.delete(name)
    }
  }

  // 重启
  resetWs() {
    console.warn('websockt connecting...')
    this.createWs()
    if (this.cachelist.size) return
    // 重启成功设置参数
    const cachelistArray = [...this.cachelist]
    cachelistArray.forEach((item, i) => {
      const indexValue = JSON.parse(item[1])
      indexValue.name = item[0]
      cachelistArray[i] = indexValue
    })
    this.setMsg(cachelistArray)
    this.start(cachelistArray)
  }

  // 错误监听
  error(callback) {
    this.ws.onerror = callback
  }

  // 关闭触发
  close(e) {
    clearInterval(this.heartBeatTimer)
    this.resetWs()
  }
}

export default webSocket
